import time
import os
import io
import cv2
from PIL import Image,ImageDraw
from pathlib import Path
from DrissionPage import ChromiumOptions ,ChromiumPage,SessionPage
from 我的工具 import pathUtils
from loguru import logger
class RPGIMG:
    def __init__(self):
        self.deskPath = pathUtils.levelPath(os.path.abspath(__file__), 2)
        self.reportImgPath = pathUtils.mkdirs(self.deskPath + "/jfb/images")

    def _parse_bg_captcha(self,img, save_path=None):
        """
        滑块乱序背景图还原
        :param img: 图片路径str/图片路径Path对象/图片二进制
            eg: 'assets/bg.webp'
                Path('assets/bg.webp')
        :param save_path: 保存路径, <type 'str'>/<type 'Path'>; default: None
        :return: 还原后背景图 RGB图片格式
        """
        if isinstance(img, (str, Path)):
            _img = Image.open(img)
        elif isinstance(img, bytes):
            _img = Image.open(io.BytesIO(img))
        else:
            raise ValueError(f'输入图片类型错误, 必须是<type str>/<type Path>/<type bytes>: {type(img)}')
        # 图片还原顺序, 定值
        _Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43,
               42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]
        w_sep, h_sep = 10, 80

        # 还原后的背景图
        new_img = Image.new('RGB', (260, 160))

        for idx in range(len(_Ge)):
            x = _Ge[idx] % 26 * 12 + 1
            y = h_sep if _Ge[idx] > 25 else 0
            # 从背景图中裁剪出对应位置的小块
            img_cut = _img.crop((x, y, x + w_sep, y + h_sep))
            # 将小块拼接到新图中
            new_x = idx % 26 * 10
            new_y = h_sep if idx > 25 else 0
            new_img.paste(img_cut, (new_x, new_y))
        if save_path is not None:
            save_path = Path(save_path).resolve().__str__()
            new_img.save(save_path)
        return new_img

    def _move(self,dirver):
        downImg = SessionPage()
        time.sleep(0.3)
        dirver.ele(
            "css:body > div.gt_holder.gt_popup.gt_show > div.gt_popup_wrap > div.gt_popup_box > div.gt_widget > div.gt_bottom > a.gt_refresh_button").click()
        dirver.listen.start()  # 启动监听
        imgList = dirver.listen.steps(2, timeout=2)  # 监听两个图片包
        fileName = None
        for i in imgList:
            downImg.get(i.url)
            data = downImg.raw_data  # 图片字节
            fileName = i.url.split("/")[::-1][0]
            with open(fileName, "wb") as fp:
                fp.write(data)  # 保存图片
            if fileName.endswith("webp"):  # 是否是混淆图片
                webp = fileName.split(".")[0] + "webp.png"  # 还原半成品图片名
                self._parse_bg_captcha(fileName, webp)  # 解混淆并保存
                img = Image.open(webp)  # 打开半成品图片
                newImg1 = img.crop((0, 0, img.width, 36))  # 切出上部分
                newImg2 = img.crop((0, 80, img.width, img.height))  # 切出下部分
                lastImg = Image.new("RGB", (img.width, 110))  # 成品图
                lastImg.paste(newImg1, (0, 0))
                lastImg.paste(newImg2, (0, 36))
                lastImg.save(fileName.split(".")[0] + "last.png")
        dirver.listen.stop()

        bgIMG = cv2.imread(fileName)  # 加载缺口图
        lastIMG = cv2.imread(fileName.split(".")[0] + "last.png")  # 加载成品图

        bg_edge = cv2.Canny(bgIMG, 100, 200)  # 识别图片边缘
        tp_edge = cv2.Canny(lastIMG, 100, 200)

        bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)  # 转换图片格式
        tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)

        res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)  # 缺口匹配
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
        x = max_loc[0]  # 滑块在验证图片的x坐标（左边）
        os.remove(fileName)
        os.remove(fileName.split(".")[0] + ".webp")
        os.remove(fileName.split(".")[0] + "webp.png")
        os.remove(fileName.split(".")[0] + "last.png")
        xp = 'css:body > div.gt_holder.gt_popup.gt_show > div.gt_popup_wrap > div.gt_popup_box > div.gt_slider > div.gt_slider_knob.gt_show'  # 滑块按钮
        dirver.actions.hold(xp).move(x) #点击移动
        dirver.actions.release(xp)  # 松开
        return dirver.ele('.gt_info_type').text

    def _lastIMG(self, fileName, num=1,noTime=False):
        # 打开图片
        img = Image.open("a.png")
        a = 40 * num
        img = img.crop((296, 133, 1096, 515 + a))
        if noTime:
            img = img.crop((0, 0, 450, 510 + a))
        draw = ImageDraw.Draw(img)
        draw.line([(2, 2), (447, 2), (447, 42), (2, 42), (2, 2)], width=3, fill='red')
        filename = "/" +fileName + ".png"
        logger.info(f"截图完成： {self.reportImgPath + filename}")
        # TODO 年报
        img.save(self.reportImgPath + filename)

    def main(self,fineName,ID,userID,name,phone,num,noTime):
        co = ChromiumOptions()
        co.incognito()
        co.headless()
        co.set_argument('--no-sandbox')
        dirver = ChromiumPage(co)
        dirver.get("https://gsxt.amr.jiangxi.gov.cn/gsxt.nb/html/login/index.html###")
        time.sleep(0.2)
        dirver.remove_ele("#float_icon2") #移除移动框
        time.sleep(0.2)
        try:
            dirver.ele("css:body > div.layout > main > div > div.lzw_08 > span:nth-child(3)").click() # 信息填取框
        except:
            dirver.ele("x:/html/body/div[6]/main/div/div[1]/span[3]").click()
        dirver.ele('x://*[@id="UNISCID2"]').input(ID)      #ID
        dirver.ele('x://*[@id="CERNO2"]').input(userID.upper()) #身份证
        dirver.ele('x://*[@id="NAME2"]').input(name) # 姓名
        dirver.ele('x://*[@id="MOBTEL2"]').input(phone) #手号
        dirver.ele('x://*[@id="submit"]').click()     # 去登陆
        for i in range(3):         # 过滑块
            try:
                text = self._move(dirver)
                if "失败" not in text:
                    break
            except:
                pass
        logger.success("登录成功")
        time.sleep(2)    #等待滑块成功响应
        dirver.refresh()  #刷新进入页面
        time.sleep(2)  #等待数据加载
        dirver.get_screenshot("a.png", right_bottom=(2135, 1369)) #全图
        self._lastIMG(fineName,num,noTime)
        dirver.quit(force=True)

RPGIMG().main("haha","92360981MA7CLHR03G","362202197712216125","熊兰珍","13177582717",2,False)
